package com.lamda.worker;

import com.lamda.worker.command.CommandExecutor;
import com.lamda.worker.config.ApplicationSettings;
import com.lamda.worker.constraints.Configuration;
import com.lamda.worker.vo.ResultVo;
import org.apache.log4j.Logger;
import org.izao.DataCallBack;
import org.izao.DataEvent;
import org.izao.DataListener;
import org.izao.IZaoClient;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by MJiao on 15/8/27.
 */
@Component
public class WorkerHolder {


    private static Logger LOGGER = Logger.getLogger(WorkerHolder.class);


    private IZaoClient iZaoClient;

    //@Autowired
    private ApplicationSettings applicationSettings;

    public ApplicationSettings getApplicationSettings() {
        return applicationSettings;
    }

    public void setApplicationSettings(ApplicationSettings applicationSettings) {
        this.applicationSettings = applicationSettings;
    }

    @Autowired
    private CommandExecutor commandExecutor;

    public WorkerHolder() {


    }

    public void registerEvent() {
        //开机
        this.iZaoClient.on("vps.start", new DataListener() {
                    @Override
                    public void receiveData(DataEvent event) {
                        //需要向服务器响应结果
                        boolean needResResult = isNeedResResultToServer(event);
                        String computerName = event.getMessage().getJSONObject("msg").getString("computerName");
                        String vmName = event.getMessage().getJSONObject("msg").getString("vmName");

                        //event.getMessage().remove("route");

                        try {
                            ResultVo resultVo = commandExecutor.executeStart(computerName, vmName);
                            //将执行结果返回给服务器断
                            event.getMessage().put("succ", resultVo.isSucc());
                            event.getMessage().put("msg", resultVo.getResult());

                        } catch (IOException e) {
                            e.printStackTrace();
                            event.getMessage().put("succ", true);
                            event.getMessage().put("msg", "执行命令出错");
                        }
                        WorkerHolder.this.reportVpsStatus();

                        WorkerHolder.this.iZaoClient.sendMessage(event.getMessage().toString()+"\r\n");


                    }
                }

        );
        iZaoClient.on(Configuration.WorkerRoute.POWER_OFF, new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                //需要向服务器响应结果
                boolean needResResult = isNeedResResultToServer(event);
                String computerName = event.getMessage().getJSONObject("msg"). getString("computerName");
                String vmName = event.getMessage().getJSONObject("msg").getString("vmName");

                //event.getMessage().remove("route");

                try {
                    ResultVo resultVo = commandExecutor.executeStop(computerName, vmName, false);
                    //将执行结果返回给服务器断
                    event.getMessage().put("succ", resultVo.isSucc());
                    event.getMessage().put("msg", resultVo.getResult());

                } catch (IOException e) {
                    e.printStackTrace();
                    event.getMessage().put("succ", true);
                    event.getMessage().put("msg", "执行命令出错");
                }

                WorkerHolder.this.reportVpsStatus();

                WorkerHolder.this.iZaoClient.sendMessage(event.getMessage().toString());


            }
        });
        iZaoClient.on(Configuration.WorkerRoute.RESTART, new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                //需要向服务器响应结果
                boolean needResResult = isNeedResResultToServer(event);
                String computerName = event.getMessage().getJSONObject("msg"). getString("computerName");
                String vmName = event.getMessage().getJSONObject("msg").getString("vmName");

                //event.getMessage().remove("route");

                try {
                    ResultVo resultVo = commandExecutor.executeRestart(computerName, vmName);
                    //将执行结果返回给服务器断
                    event.getMessage().put("succ", resultVo.isSucc());
                    event.getMessage().put("msg", resultVo.getResult());

                } catch (IOException e) {
                    e.printStackTrace();
                    event.getMessage().put("succ", true);
                    event.getMessage().put("msg", "执行命令出错");
                }

                WorkerHolder.this.reportVpsStatus();

                WorkerHolder.this.iZaoClient.sendMessage(event.getMessage().toString());


            }
        });
        iZaoClient.on(Configuration.WorkerRoute.CREATE_SNAPSHOT, new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                //需要向服务器响应结果
                boolean needResResult = isNeedResResultToServer(event);
                String computerName = event.getMessage().getJSONObject("msg"). getString("computerName");
                String vmName = event.getMessage().getJSONObject("msg").getString("vmName");

                //event.getMessage().remove("route");

                try {
                    ResultVo resultVo = commandExecutor.executeCreateSnapshot(computerName, vmName);
                    //将执行结果返回给服务器断
                    event.getMessage().put("succ", resultVo.isSucc());
                    event.getMessage().put("msg", resultVo.getResult());

                } catch (IOException e) {
                    e.printStackTrace();
                    event.getMessage().put("succ", true);
                    event.getMessage().put("msg", "执行命令出错");
                }

                WorkerHolder.this.reportVpsStatus();

                WorkerHolder.this.iZaoClient.sendMessage(event.getMessage().toString());


            }
        });
        iZaoClient.on(Configuration.WorkerRoute.RESTORE_SNAPSHOT, new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                //需要向服务器响应结果
                boolean needResResult = isNeedResResultToServer(event);
                String computerName = event.getMessage().getJSONObject("msg"). getString("computerName");
                String vmName = event.getMessage().getJSONObject("msg").getString("vmName");

                //event.getMessage().remove("route");

                try {
                    ResultVo resultVo = commandExecutor.executeRestoreSnapshot(computerName, vmName);
                    //将执行结果返回给服务器断
                    event.getMessage().put("succ", resultVo.isSucc());
                    event.getMessage().put("msg", resultVo.getResult());

                } catch (IOException e) {
                    e.printStackTrace();
                    event.getMessage().put("succ", true);
                    event.getMessage().put("msg", "执行命令出错");
                }

                WorkerHolder.this.reportVpsStatus();

                WorkerHolder.this.iZaoClient.sendMessage(event.getMessage().toString());


            }
        });

        iZaoClient.on(Configuration.WorkerRoute.INIT_VPS_SNAPSHOT, new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                //需要向服务器响应结果
                boolean needResResult = isNeedResResultToServer(event);
                String computerName = event.getMessage().getJSONObject("msg"). getString("computerName");
                String vmName = event.getMessage().getJSONObject("msg").getString("vmName");

                //event.getMessage().remove("route");

                try {
                    //ResultVo resultVo = commandExecutor.executeRestoreSnapshot(computerName, vmName);
                    ResultVo resultVo = commandExecutor.executeInitVpsSnapshot(computerName, vmName);
                    //将执行结果返回给服务器断
                    event.getMessage().put("succ", resultVo.isSucc());
                    event.getMessage().put("msg", resultVo.getResult());

                } catch (IOException e) {
                    e.printStackTrace();
                    event.getMessage().put("succ", true);
                    event.getMessage().put("msg", "执行命令出错");
                }

                WorkerHolder.this.reportVpsStatus();

                WorkerHolder.this.iZaoClient.sendMessage(event.getMessage().toString());


            }
        });

        iZaoClient.on("onChat", new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                System.out.println("onChat = " + event.getMessage());
            }
        });

        iZaoClient.on("connectFail", new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                LOGGER.warn("connectFail = " + event.getMessage());
            }
        });
        /**
         * 连接成功
         */
        iZaoClient.on("connect", new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                LOGGER.info("connect success! ");

                WorkerHolder.this.getiZaoClient().setStatus(IZaoClient.Status.Connected);

                reportVpsStatus();


            }
        });
        /**
         * 断开连接
         */
        iZaoClient.on("disconnect", new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                LOGGER.warn("Disconnect ! ");
                //重置链接状态
                WorkerHolder.this.getiZaoClient().setStatus(IZaoClient.Status.DisConneted);
                //立即重连
                WorkerHolder.this.getiZaoClient().connect();

            }
        });

        iZaoClient.on("error", new DataListener() {
            @Override
            public void receiveData(DataEvent event) {
                LOGGER.warn("event.getMessage() = " + event.getMessage());
            }
        });
    }

    /**
     * 向服Master务器报告vps的运行情况
     */
    public void reportVpsStatus() {

        JSONObject registerJsonObject = new JSONObject();
        registerJsonObject.put("hostIp", applicationSettings.getWorkerIp());
        registerJsonObject.put("hostname", "北京");
        if (applicationSettings.getRemark()!=null){
            registerJsonObject.put("remark", "北京");
        }

        LOGGER.info("******************************** "+registerJsonObject.getString("remark")+applicationSettings.getWorkerHostname());
        LOGGER.info("要获取本地的vps信息后上传到服务器");
        //要获取本地的vps信息后上传到服务器
        try {
            registerJsonObject.put("vpsList", commandExecutor.executeGetAllVps());
        } catch (IOException e) {
            e.printStackTrace();
            registerJsonObject.put("vpsList", new ArrayList());
        }

        iZaoClient.request(Configuration.WorkerRoute.REGISTER, registerJsonObject, new DataCallBack() {
            @Override
            public void responseData(JSONObject message) {
                System.out.println(" message = " + message);
            }
        });
    }


    public IZaoClient getiZaoClient() {
        return iZaoClient;
    }
    public boolean isNeedResResultToServer(DataEvent event) {
        return event.getMessage().has("serverReqId");
    }

    public void setiZaoClient(IZaoClient iZaoClient) {
        this.iZaoClient = iZaoClient;
    }
}
